//
//$Id: utils.cpp 652 2011-02-19 11:16:56Z Oleg.Bulychov $
#include "stdafx.h"
#include "include/utils.h"
#include "include/sets.h"
#include "include/fa.h"
#include "include/re.h"


using namespace std;
using namespace rapidxml;

std::string OpenBracket(Brackets_Type const bt)
{
    switch (bt)
    {
        case PARENTHESES:  return "("; 
        case BRACKETS:     return "["; 
        case BRACES:       return "{"; 
        case LATEX_BRACES: return "\\{";
        default:           return "";
    }
}

std::string CloseBracket(Brackets_Type const bt)
{
    switch (bt)
    {
        case PARENTHESES:  return ")"; 
        case BRACKETS:     return "]"; 
        case BRACES:       return "}"; 
        case LATEX_BRACES: return "\\}";
        default:           return "";
    }
}

string MakeLabel(string const& pfx, u_t const id, Labels_Type const lt)
{
	switch (lt)
	{
	   case TXT:   return pfx + IntToString(id);
	   case LATEX: return (pfx == "" ? IntToString(id) : pfx + "_{" + IntToString(id) + "}");
	   case HTML:  return (pfx == "" ? IntToString(id) : "<I>" + pfx + "</I>" + "<SUB>" + IntToString(id) + "</SUB>");
	   default:    return pfx + IntToString(id);
	}
}

std::string StateInOutLabel(bool const in, bool const fin,  Labels_Type const lt)
{
	switch (lt)
	{
	   case TXT:   
   			if (in && fin)
			{
				return "<->";
			}
			else
			{
				if (in)
				{
					return "-->";
				}
				else
				{
					if (fin)
					{
						return "<--";
					}
					else
					{
						return "   ";
					}
				}
			}

	   case LATEX: 
			if (in && fin)
			{
				return "\\leftrightarrows";
			}
			else
			{
				if (in)
				{
					return "\\rightarrow";
				}
				else
				{
					if (fin)
					{
						return "\\leftarrow";
					}
					else
					{
						return "";
					}
				}
			}

	   default: return "";
	}
}

u_t Min(u_t a, u_t b, u_t c)
{
    if (b < c)
    {
        if (a < b)
            return a;
        else
            return b;
    }
    else
    {
        if (a < c)
            return a;
        else
            return c;
    }
}

std::string GetFileExtension(string const& filename)
{
    u_t pos = filename.rfind('.');

    if (pos == filename.npos)
	{
        return ""; 
	}
    else
	{
        return filename.substr(pos+1);
	}
}

std::string CreatePath(string const& dir, string const& file)
{
    u_t n = dir.length();

    if ((dir[n-1] == '\\') || (dir[n-1] == '/'))
	{
        return dir + file;
	}

    u_t pos = dir.find_last_of("/\\");

    if (pos == dir.npos)
	{
        return dir + "/" + file;
	}

    if (dir[pos] == '\\')
	{
        return dir + "\\" + file;
	}
    else
	{
        return dir + "/" + file;
	}
}

void SplitFileName(string const& path, string& dir, string& file)
{
    u_t pos = path.find_last_of("/\\");

    dir  = path.substr(0, pos);
    file = path.substr(pos+1);
}

void SplitFileName(string const& path, string& dir, string& name, string& ext)
{
    SplitFileName(path, dir, name);
    
    u_t pos = name.find_last_of(".");
    
    if (pos == name.npos)
    {
        ext = "";
    }
    else
    {
        ext  = name.substr(pos+1);
        name = name.substr(0, pos);
    }
}

bool EquivalentRows(Bool_Matrix const& m, u_t const i, u_t const j) 
{
    for (u_t k = 0; k < m[i].size(); ++k)
    {
        if (m[i][k] != m[j][k])
		{
            return false;
		}
    }

    return true;
}

bool EquivalentColumns(Bool_Matrix const& m, u_t const i, u_t const j) 
{
    for (u_t k = 0; k < m.size(); ++k)
    {
        if (m[k][i] != m[k][j])
		{
            return false;
		}
    }

    return true;
}

bool AllOnesInRow(Bool_Matrix const& m, u_t const i, Subset const& s)
{
    for (Subset::const_iterator it = s.begin(); it != s.end(); ++it)
    {
        if (m[i][*it] == 0)
		{
            return false;
		}
    }

    return true;
}

bool AllOnesInColumn(Bool_Matrix const& m, u_t const j, Subset const& s)
{
	for (Subset::const_iterator it = s.begin(); it != s.end(); ++it)
    {
        if (m[*it][j] == 0)
		{
            return false;
		}
    }

    return true;
}

u_t OnesCount(Bool_Matrix const& m)
{
    u_t num = 0;

    for (u_t i = 0; i < m.size(); ++i)
    {
        for (u_t j = 0; j < m[i].size(); ++j)
		{
            if (m[i][j])
			{
                ++num;
			}
		}
    }

    return num;
}

xml_node<>* GetNode(string const& file, vector<char>& buffer, xml_document<>& doc, string const& NodeName)
{
	ifstream ifs(file.c_str());

	if (!ifs)
	{
		//cout << "GetNode error: file open error!" << endl;
		return NULL;
	}
	
	ifs.seekg(0, std::ios::end);
    streamsize length = ifs.tellg();
	ifs.seekg(0, std::ios::beg);

	if (length <= 0)
	{
		//cout << "GetNode error: file is empty!" << endl;
		return NULL;
	}

	buffer.resize(size_t(length + 1));
	ifs.read(&buffer[0], length);

	doc.parse<0>(&buffer[0]);

	//cout << doc << endl;
	// process application node
	xml_node<>* node = doc.first_node(kAppXmlNode.c_str(), 0, false);
	
	if (node == NULL)
	{
		//cout << "GetNode error: '" << kAppXmlNode << "' node is missing!" << endl;
	    return NULL;
	}

	return node->first_node(NodeName.c_str(), 0, false);
}

bool HasFANode(string const& file)
{
	vector<char> buffer;
	xml_document<> doc;
	xml_node<>* node = GetNode(file, buffer, doc, kFAXmlNode);

	return node != NULL;
}

bool HasRENode(string const& file)
{
	vector<char> buffer;
	xml_document<> doc;
	xml_node<>* node = GetNode(file, buffer, doc, kREXmlNode);

	return node != NULL;
}

//EOF!
